﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
using System.Xml.Serialization;
using TSharp.Core.Util;
using TSharp.Core.Util.Config;
using TSharp.Core.Pattern;
using TSharp.Core.Caching;

namespace TSharp.Core.Util
{
    /// <summary>
    /// 
    /// </summary>
    /// <author>
    /// tangjingbo
    /// </author>
    /// <remarks>
    /// tangj15 at 2012-6-8 9:52
    /// </remarks>
    public interface ISerializable
    {
        /// <summary>
        /// 配置文件全路径名
        /// 默认：winform 在应用程序目录；web应用程序默认bin目录。
        /// </summary>
        /// <value>
        /// The full name of the config file.
        /// </value>
        [XmlIgnore, SoapIgnore]
        string FileFullName { get; }
    }

    /// <summary>
    /// Xml文件读写辅助
    /// <para>by tangjingbo at 2011-6-14 10:19</para>
    /// </summary>
    public sealed class SerializeHelper
    {
        private static readonly string DefaultStoreFileFolder;
        private readonly FormatType _type;

        /// <summary>
        /// Xmltializes a new instance of the <see cref="SerializeHelper"/> class.
        /// </summary>
        /// <param name="type">The file name or file full path and name.</param>
        public SerializeHelper(FormatType type)
        {
            _type = type;
        }

        private SerializeHelper()
            : this(FormatType.Xml)
        { }

        #region ctor
        /// <summary>
        /// 默认存储辅助实例
        /// </summary>
        public static readonly SerializeHelper Current;
        static SerializeHelper()
        {
            try
            {
                DefaultStoreFileFolder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData);
            }
            catch
            {
                try
                {
                    DefaultStoreFileFolder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData);
                }
                catch
                {
                    DefaultStoreFileFolder = (AppDomain.CurrentDomain.SetupInformation.ApplicationBase);
                }
            }
            try
            {
                DefaultStoreFileFolder = Path.Combine(DefaultStoreFileFolder, "TSharper");
                var name = Process.GetCurrentProcess().ProcessName;
                if (string.IsNullOrEmpty(name))
                    name = "tsharp";
                name = name.Trim(Path.GetInvalidPathChars());
                DefaultStoreFileFolder = Path.Combine(DefaultStoreFileFolder, name);
                if (!Directory.Exists(DefaultStoreFileFolder))
                    Directory.CreateDirectory(DefaultStoreFileFolder);
            }
            catch (Exception)
            {
            }
            Current = new SerializeHelper();
        }

        #endregion

        /// <summary>
        /// 创建Xml辅助对象
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public SerializeHelper New(FormatType type)
        {
            return new SerializeHelper(type);
        }
        /// <summary>
        /// Deserializes this instance.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public SerializeHelper Deserialize<T>(out T o) where T : ISerializable, new()
        {
            var x = ThreadSingletonHelper<Formatter<T>>.GetOrAdd(() =>
            {
                return new Formatter<T>(_type);
            });
            var type = typeof(T);
            var filePath = Path.Combine(DefaultStoreFileFolder, type.FullName);
            o = x.DeserializeFromFile(filePath);
            return this;
        }

        /// <summary>
        /// Serializes this instance.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public SerializeHelper Serialize<T>(T o) where T : ISerializable, new()
        {
            var x = ThreadSingletonHelper<Formatter<T>>.GetOrAdd(() =>
            {
                return new Formatter<T>(_type);
            });
            var type = typeof(T);
            var fileFullPath = Path.Combine(DefaultStoreFileFolder, type.FullName);
            x.SerializeToFile(o, fileFullPath);
            return this;
        }

    }

}
